﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Timers;
using System.ComponentModel;

namespace Pomo
{
    public class Pomodoro : INotifyPropertyChanged
    {
        public Pomodoro()
        {
            timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
        }

        public string Task { get; set; }

        private int _durationMinutes;
        public int DurationMinutes
        {
            get { return _durationMinutes; }
            set
            {
                if (Status == StatusType.Working) throw new InvalidOperationException("Cannot change the duration of a Pomodoro after it has started.");
                else
                {
                    _durationMinutes = value;
                    resetTotalRemainingSeconds();
                    NotifyPropertyChanged("DurationMinutes");
                }
            }
        }

        private int _breakDurationMinutes;
        public int BreakDurationMinutes
        {
            get { return _breakDurationMinutes; }
            set
            {
                _breakDurationMinutes = value;
                resetTotalRemainingSeconds();
                NotifyPropertyChanged("BreakDurationMinutes");
            }
        }

        private void resetTotalRemainingSeconds()
        {
            totalRemainingSeconds = (_durationMinutes * 60) + (_breakDurationMinutes * 60);
        }

        private int _warnSeconds = 15;
        public int WarningSeconds
        {
            get { return _warnSeconds; }
            set { _warnSeconds = value; }
        }

        int _totalRemainingSeconds;
        int totalRemainingSeconds
        {
            get { return _totalRemainingSeconds; }
            set 
            { 
                _totalRemainingSeconds = value;
                NotifyPropertyChanged("RemainingMMSS");
            }
        }
        
        int _mins;
        int _secs;
        public string RemainingMMSS 
        { 
            get 
            {
                if (Status == StatusType.Breaking)
                {
                    _mins = _totalRemainingSeconds / 60;
                    _secs = _totalRemainingSeconds % 60;
                }
                else
                {
                    _mins = (int)Math.Max(0, (_totalRemainingSeconds / 60) - BreakDurationMinutes);
                    _secs = (_totalRemainingSeconds) % 60;
                }

                return _mins.ToString("00") + ":" + _secs.ToString("00");
            }
        }

        Timer timer = new Timer(1000);

        public StatusType PreviousStatus { get; set; }
        private StatusType _status;
        public StatusType Status
        {
            get { return _status; }
            private set 
            {
                if (_status != value)
                {
                    PreviousStatus = _status;
                    _status = value;
                    NotifyPropertyChanged("Status");
                }
            }
        }

        public enum StatusType
        {
            Stopped,
            Working,
            WorkPaused,
            Breaking,
            BreakPaused
        }

        void timer_Elapsed(object sender, ElapsedEventArgs e)
        {
            this.totalRemainingSeconds--;
            if (totalRemainingSeconds == 0)
            {
                Stop();
            }
            else if (totalRemainingSeconds == _breakDurationMinutes * 60 )
            {
                Status = StatusType.Breaking;
            }
        }

        public void Pause() 
        {
            timer.Stop();
            Status = (Status == StatusType.Breaking) ? StatusType.BreakPaused : StatusType.WorkPaused;
        }
        
        public void Start()
        {
            timer.Start();
            Status = StatusType.Working;
        }

        public void Continue()
        {
            timer.Start();
            Status = (Status == StatusType.BreakPaused) ? StatusType.Breaking : StatusType.Working;
        }

        public void Stop()
        {
            timer.Stop();
            Status = StatusType.Stopped;
            resetTotalRemainingSeconds();
        }

        public void StartPauseContinue()
        {
            if (Status == StatusType.WorkPaused || Status == StatusType.BreakPaused) Continue();
            else if (Status == StatusType.Working || Status == StatusType.Breaking) Pause();
            else Start();
        }

        public event PropertyChangedEventHandler PropertyChanged;
        protected virtual void NotifyPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }


}
